﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;

namespace Dapper.Common
{
    public static class EnumExtender
    {
        /// <summary>
        /// 获取枚举描述
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        public static string GetText(this Enum e)
        {
            Type type = typeof(DescriptionAttribute);
            FieldInfo fi = e.GetType().GetField(e.ToString());
            if(fi == null)
                return e.ToString();

            object[] arr = fi.GetCustomAttributes(type, true);
            if(arr.Length > 0)
                return ((DescriptionAttribute)arr[0]).Description;

            return e.ToString();
        }

        public static string GetText(this PropertyInfo pi)
        {
            foreach(object obj in pi.GetCustomAttributes(false))
            {
                if(obj is DescriptionAttribute)
                    return ((DescriptionAttribute)obj).Description;
            }
            return pi.Name;
        }

        /// <summary>
        /// 字符串转换成枚举类型
        /// </summary>
        /// <typeparam name="U">枚举类型</typeparam>
        /// <param name="value">字符串</param>
        /// <returns>枚举值</returns>
        public static U Parse<U>(this string value)
        {
            try
            {
                Type type = typeof(U);
                return (U)Enum.Parse(type, value);
            }
            catch
            {
                return default(U);
            }
        }

        public static U Parse<U>(this object obj)
        {
            try
            {
                Type type = typeof(U);
                return (U)Enum.Parse(type, obj.ToString());
            }
            catch
            {
                return default(U);
            }
        }

        public static List<EnumItem> GetDatas(Type type)
        {
            List<EnumItem> items = new List<EnumItem>();

            FieldInfo[] infos = type.GetFields(BindingFlags.Public | BindingFlags.Static);
            for(int i = 0; i < infos.Length; i++)
            {
                EnumItem item = new EnumItem();

                FieldInfo info = infos[i];

                object[] _objs = infos[i].GetCustomAttributes(typeof(UnbindEnumExtendedAttribute), false);
                if(_objs.Length > 0)
                    continue;

                item.Name = info.Name;
                item.Value = ((int)Enum.Parse(type, info.Name)).ToString();

                object[] objs = info.GetCustomAttributes(typeof(DescriptionAttribute), false);

                if(objs == null || objs.Length == 0)
                {
                    objs = info.GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if(objs == null || objs.Length == 0)
                    {
                        item.Text = info.Name;
                    }
                    else
                    {
                        DescriptionAttribute da = (DescriptionAttribute)objs[0];
                        item.Text = da.Description;
                    }
                }
                else
                {
                    DescriptionAttribute da = (DescriptionAttribute)objs[0];
                    item.Text = da.Description;
                }
                items.Add(item);
            }
            items.Sort();
            return items;
        }

        /// <summary>
        /// 判断某枚举值中是否包含在定义的值中
        /// </summary>
        /// <param name="e">当前的枚举值</param>
        /// <param name="enums">用户定义的枚举值</param>
        /// <returns></returns>
        public static bool Belongs<U>(this U e, params U[] enums)
        {
            foreach(U _e in enums)
            {
                if(_e.Equals(e))
                    return true;
            }
            return false;
        }
    }

    public class EnumItem : IComparable<EnumItem>
    {
        public string Name
        {
            get;
            set;
        }

        public string Text
        {
            get;
            set;
        }

        public string Value
        {
            get;
            set;
        }

        public bool IsSelected
        {
            get { return true; }
        }

        public int CompareTo(EnumItem other)
        {
            return Convert.ToInt32(Value) - Convert.ToInt32(other.Value);
        }
    }

    /// <summary>
    /// Enum类型进行绑定的时候，不需要绑定的项的标记
    /// </summary>
    [AttributeUsage(AttributeTargets.All)]
    public class UnbindEnumExtendedAttribute : Attribute
    {
    }
}